<?php
/**
 * Глобальный класс управления справочниками
 * 
 * @category Phorm
 * @package Dictionaries
 * @name /Phorm/Dictionaries.php
 * @copyright phorm.ru
 * @since 10.07.2012
 * @author vladimir@kachalov.net
 */

class Phorm_Dictionaries extends Phorm_Model {
	
	/**
	 * Возвращает список справочников
	 *
	 * @param array $options Массив опций
	 * @return array
	 * @todo Бросить добавление сортировок и постраничной выборки в модель отдельными методами или придумать иной способ избежать дублирования
	 */
	
	public function getDictionariesList($options = array()) {
		
		$select = $this->_db->select()
				-> from(array('AA'=>'pw_dictionaries'), 
							new Zend_Db_Expr("SQL_CALC_FOUND_ROWS AA.*, 1 actions, 
											 (SELECT COUNT(*) FROM pw_dictionaries_entries WHERE dictionaryid=AA.dictionaryid AND isexist='yes') entries"))
				-> where('isexist=?','yes');
				
		// Сортировки
		if(isset($options['sortField']) && in_array($options['sortField'],$this->getTableCols('pw_dictionaries'))) {
			$sortOrder = isset($options['sortOrder']) && $options['sortOrder']=='desc' ? ' DESC' : ' ASC';
			$select->order($options['sortField'].$sortOrder);
		} else {
			$select->order('dictionaryname');
		}
		
		// Устанавливаем количество отдаваемых строк
		// Если передан 0, то возвращаем все найденные строки
		if (isset($options['rowsperpage']) && $options['rowsperpage']>0) {
			$select -> limitPage($this->getCurrentPage(),(int)$options['rowsperpage']);
		} elseif(!isset($options['rowsperpage'])) {
			$select -> limitPage($this->getCurrentPage(),$this->getPerPage());
		}
		
		// Добавляем условие, если выборка для фронтенда
		if($this->getModule()!='control') $select -> where('visible=?','yes');
				
		return $this->_db->fetchAll($select);
		
	}
	
	
	/**
	 * Возвращает список справочников  в виде массива пар
	 *
	 * @return array
	 */
	
	public function getDictionariesListAsPairs() {
		
		$select = $this->_db->select()
				-> from('pw_dictionaries',array('dictionaryid','dictionaryname'))
				-> where('isexist=?','yes')
				-> order('dictionaryname');
				
		if($this->getModule()!='control') $select -> where('visible=?','yes');
		
		return $this->_db->fetchPairs($select);
		
	}
	
	
	/**
	 * Возвращает информацию о справочнике
	 *
	 * @param int $dictionaryid Id  справочника
	 * @return array
	 */
	
	public function getDictionaryInfo($dictionaryid) {
		
		$select = $this->_db->select()
				-> from('pw_dictionaries')
				-> where('isexist=?','yes')
				-> where('dictionaryid=?',$dictionaryid);
				
		// Добавляем условие, если выборка для фронтенда
		if($this->getModule()!='control') $select -> where('visible=?','yes');
				
		return $this->_db->fetchRow($select);
		
	}
	
	
	/**
	 * Возвращает форму добавления/редактирования справочника
	 *
	 * @param string $section Секция xml-файла
	 * @return Phorm_Form
	 */
	
	public function getDictionaryForm($section = 'add') {
		
		return new Phorm_Form('forms/control/dictionaries.xml',$section);
		
	}
	
	
	/**
	 * Сохраняет данные формы добавления/редактирования справочника
	 *
	 * @param Phorm_Form $form
	 * @param mixed $data  Дополнительные данные формы. Если передана строка, то принимается как dictionaryid
	 * @return array | false
	 * @todo Вынести простую вставку/изменение в отдельный метод?
	 */
	
	public function saveDictionaryForm($form, $data = null) {
		
		if(!is_null($data) && is_string($data)) $data = array('dictionaryid'=>$data);
		$data = array_merge($form->getValues(),(array)$data);
		
		$data = $this->getFilteredValuesByTableCols('pw_dictionaries',$data);
		
		$this->_db->beginTransaction();
		
		try {
			
			// Изменение существующей записи
			if(isset($data['dictionaryid'])) {
				
				$this->_db->update('pw_dictionaries',$data,'dictionaryid='.(int)$data['dictionaryid']);
				
			// Вставка новой записи
			} else {
				
				$this->_db->insert('pw_dictionaries',$data);
				$data['dictionaryid'] = $this->_db->lastInsertId();
				
			}
			
			$this->_db->commit();						  
			return $data;
			
		} catch (Exception $e) {
			
			$this->_db->rollBack();	
			$this->_errors[] = $e->getMessage();
			
		}
		
		return false;
		
	}
	
	
	/**
	 * Удаляет справочник
	 *
	 * @param int $dictionaryid Id словаря
	 * @return boolean
	 */
	
	public function deleteDictionary($dictionaryid) {
		
		return $this->_db->update('pw_dictionaries',array('isexist'=>'no'),'dictionaryid='.(int)$dictionaryid);
		
	}
	
	
	/**
	 * Возвращает список записей в справочнике
	 *
	 * @param int $dictionaryid Id справочника
	 * @param array $options Массив опций
	 * @return array
	 */
	
	public function getEntriesList($dictionaryid, $options) {
		
		$select = $this->_db->select()
				-> from(array('AA'=>'pw_dictionaries_entries'), new Zend_Db_Expr("SQL_CALC_FOUND_ROWS AA.*, 1 actions"))
				-> join(array('BB'=>'pw_dictionaries'), 'AA.dictionaryid=BB.dictionaryid', array())
				-> where('AA.dictionaryid=?',$dictionaryid)
				-> where('AA.isexist=?','yes')
				-> where('BB.isexist=?','yes');
				
		// Сортировки
		if(isset($options['sortField']) && in_array($options['sortField'],$this->getTableCols('pw_dictionaries_entries'))) {
			$sortOrder = isset($options['sortOrder']) && $options['sortOrder']=='desc' ? ' DESC' : ' ASC';
			$select->order($options['sortField'].$sortOrder);
		} else {
			$select -> order('IF(sortorder=0,999999999,sortorder)')
					-> order('entryname');
		}
		
		// Устанавливаем количество отдаваемых строк
		// Если передан 0, то возвращаем все найденные строки
		if (isset($options['rowsperpage']) && $options['rowsperpage']>0) {
			$select -> limitPage($this->getCurrentPage(),(int)$options['rowsperpage']);
		} elseif(!isset($options['rowsperpage'])) {
			$select -> limitPage($this->getCurrentPage(),$this->getPerPage());
		}
		
		// Добавляем условие, если выборка для фронтенда
		if($this->getModule()!='control') {
			$select -> where('AA.visible=?','yes')
					-> where('BB.visible=?','yes');
		}
				
		return $this->_db->fetchAll($select);
		
	}
	
	
	/**
	 * Возвращает список записей в справочнике в виде массива пар
	 *
	 * @param int $dictionaryid Id справочника
	 * @return array
	 */
	
	public function getEntriesListAsPairs($dictionaryid) {
		
		$select = $this->_db->select()
				-> from(array('AA'=>'pw_dictionaries_entries'), array('entryid','entryname'))
				-> join(array('BB'=>'pw_dictionaries'), 'AA.dictionaryid=BB.dictionaryid', array())
				-> where('AA.dictionaryid=?',$dictionaryid)
				-> where('AA.isexist=?','yes')
				-> where('BB.isexist=?','yes');
				
		if($this->getModule()!='control') {
			$select -> where('AA.visible=?','yes')
					-> where('BB.visible=?','yes');
		}
		
		return $this->_db->fetchPairs($select);
		
	}
	
	
	/**
	 * Возвращает информацию о записи в справочнике
	 *
	 * @param int $entryid Id записи
	 * @return array
	 */
	
	public function getEntryInfo($entryid) {
		
		$select = $this->_db->select()
				-> from(array('AA'=>'pw_dictionaries_entries'))
				-> join(array('BB'=>'pw_dictionaries'),'AA.dictionaryid=BB.dictionaryid')
				-> where('AA.isexist=?','yes')
				-> where('BB.isexist=?','yes')
				-> where('entryid=?',$entryid);
				
		// Добавляем условие, если выборка для фронтенда
		if($this->getModule()!='control') {
			$select -> where('AA.visible=?','yes')
					-> where('BB.visible=?','yes');
		}
				
		return $this->_db->fetchRow($select);
		
	}
	
	
	/**
	 * Возвращает форму добавления/редактирования записи в справочнике
	 *
	 * @param string $section Секция xml-файла
	 * @return Zend_Form
	 */
	
	public function getEntryForm($section = 'addentry') {
		
		return new Phorm_Form('forms/control/dictionaries.xml',$section);
		
	}
	
	
	/**
	 * Сохраняет данные формы добавления/редактирования справочника
	 *
	 * @param Phorm_Form $form
	 * @param mixed $data  Дополнительные данные формы. Если передана строка, то принимается как entryid
	 * @return array | false
	 * @todo Вынести простую вставку/изменение в отдельный метод?
	 */
	
	public function saveEntryForm($form, $data = null) {
		
		if(!is_null($data) && is_string($data)) $data = array('entryid'=>$data);
		$data = array_merge($form->getValues(),(array)$data);
		
		$data = $this->getFilteredValuesByTableCols('pw_dictionaries_entries',$data);
		
		$this->_db->beginTransaction();
		
		try {
			
			// Изменение существующей записи
			if(isset($data['entryid'])) {
				
				$this->_db->update('pw_dictionaries_entries',$data,'entryid='.(int)$data['entryid']);
				
			// Вставка новой записи
			} else {
				
				$this->_db->insert('pw_dictionaries_entries',$data);
				$data['entryid'] = $this->_db->lastInsertId();
				
			}
			
			$this->_db->commit();						  
			return $data;
			
		} catch (Exception $e) {
			
			$this->_db->rollBack();	
			$this->_errors[] = $e->getMessage();
			
		}
		
		return false;
		
	}
	
	
	/**
	 * Удаляет запись в справочнике
	 *
	 * @param int $entryid Id записи
	 * @return boolean
	 */
	
	public function deleteEntry($entryid) {
		
		return $this->_db->update('pw_dictionaries_entries',array('isexist'=>'no'),'entryid='.(int)$entryid);
		
	}
	
}